
堆内存管理：
	堆内存与栈内存，相同点和不同点、优缺点？
	C语言没有提供管理堆内存的语句，而是标准库提供了一套管理内存的函数。
	头文件：stdlib.h

	void *malloc(size_t size);      			//速度快
	功能：从堆内存中申请内存
	size：所申请的字节数，一般使用 sizeof 计算
	返回值：所申请的内存的首地址
	注意：如果申请内存失败或者size的值为0，返回值为NULL。
		  所申请的内存没有初始化，内存是不确定的。

	当向malloc首次申请内存时，malloc会向系统申请，系统会映射33页内存交给malloc管理，之后再向malloc申请内存，
	malloc会直接从这33页内存中分配，直到用完，再向操作系统申请
			访问malloc分配的内存时，可以越界，但不要超过33页范围。

    void free(void *ptr);
	功能：释放堆内存
	ptr：需要被释放的内存的首地址，如果ptr的值不是malloc的返回值，可能会出现内存崩溃。

	练习1：计算100～1000之间所有的素数，存入堆内存中。

    void *calloc(size_t nmemb, size_t size);
	功能：从堆内存中申请内存
	nmemb：申请多块内存
	size：每块内存的字节数
	返回值：所申请的内存的首地址
	注意：所申请的内存会被初始化为0。
		如果申请内存失败或者nmemb、size的值为0，返回值为空。

	malloc与calloc函数相比，calloc的参数更清晰，内存会被初始化。
	而malloc的速度更快，如果内存需要被初始化或都整体赋值可以使用：
	
	/*
	#include <strings.h>	
	void bzero(void *s, size_t n);
	功能：把指定内存中的数据设置为0。
	s：内存的首地址
	n：内存的大小（字节数）
	*/
	
	/*
	#include <string.h>
	void *memset(void *s, int c, size_t n);
	功能：把指定的内存以字节为单位设置为指定的值
	s：内存的首地址
	c：字节中存储的数据
	n：内存的大小（字节数）
	返回值：设置后的内存的首地址
		为什么有返回值？ 
		链式调用：把函数的返回值当作另一个函数的参数，以此达到精简代码的目的。
		int* p = malloc(4);
		realloc(memset(p,1,4),8);
*/
    void *realloc(void *ptr, size_t size);
	功能：调整已经申请到的内存的大小
	ptr：已经申请内存的首地址，当ptr为NULL，相当于申请内存
	size：调整后大小，当size为0，相当于释放内存
	返回值：调整后的内存首地址
	注意：返回值要重新接收。

void*
	无类型指针（万能指针）。
	不能解引用，必须先转换成其它有效类型再解引用。
	void* 可以自动转换成任意类型指针
	任意类型的指针也可以自动转换成void*
----------------------------------------------------------------------------------------------------	
	

内存映射：
	当程序运行后，就会有0～4G地址范围（并不能全部访问，地址没有对应物理内存）。
	如果访问了没有映射过的地址（逻辑地址）就会产生段错误。
	当首次使用malloc申请内存时，malloc此时没有内存可分配，它会向操作系统申请进行内存映射，操作系统会直接映射33页内存交给malloc管理，当再次使用malloc申请内存时，malloc会把已经有的33页内存进行分配。

----------------------------------------------------------------------------------------------------	
	
内存管理：
	malloc分配的每一块内存之间至少相隔4个字节（存储的是下一块要分配的内存地址），如果这4个字节的内容被破坏会影响下次的内存分配。
	如果在内存分配后再破坏这4个字节，会影响这块内存的释放。 （补齐对齐）
	堆内存越界的后果：
		1、破坏malloc的维护信息，可能造成申请或释放时的错误
			malloc.c:2451: sYSMALLOc: Assertion
			free(): invalid pointer: 0x0846xxxx
		2、脏数据：没有被malloc分配的内存虽然也可以使用，但当malloc再次把它分配后，之前存储的数据会被破坏（有多个指针指向了同一块内存）。
		3、段错误：越界范围超过33页。
		4、一切正常：访问用来对齐的字节。
----------------------------------------------------------------------------------------------------	
	
内存碎片：
	已经被释放但不能再次使用的内存叫内存碎片。
	由于申请时间的释放时间不匹配造成已经释放的内存不能继续使用。
	内存碎片是不可能的杜绝，可能尽量减少。
	如何减少内存碎片的产生：
		1、尽量使用栈内存（函数）。
		2、尽量申请大块内存。
		3、不要频繁的申请释放内存。


----------------------------------------------------------------------------------------------------	
	
内存泄漏： 由于指针被错误赋值、业务逻辑错误导致，堆内存无法被释放，而需要使用时只能再次申请，
			长期积累导致可用的内存越来越少，速度越来越慢，这种情况叫内存泄漏。
	1.指针管理失败，指向其他位置
	2.free语句没有执行到
	3.free语句忘记写
	前提：程序没有结束，
	当程序结束后，操作系统所分配给它的资源会被全部回收。
	但是一般服务器的程序不能轻易停止。

	如何避免：
		1、谁申请谁释放。
		2、谁知道该释放谁释放。
----------------------------------------------------------------------------------------------------	
	



